var fs = require("fs");
var wavName = "Rec 0004";
var wavRead = fs.readFileSync(`./wav/${wavName}.wav`);

const NUM_2_SEMITONES_DIC = {
    1: -9,
    2: -7,
    3: -5,
    4: -4,
    5: -2,
    6: 0,
    7: 2
}

let logTimes = 0;
function logWithTimes(a, times = 1) {
    if (logTimes < times) {
        console.log(a);
        logTimes++;
    }
}


// A4 la 440HZ; A5 880HZ
// 2^(1/12)
// 一个八度12个音
// 声道数
let tracks = 2;
// 采样精度 默认：用2个字节存储一个音
let samplingPrecision = 2;
// 音调
let beeeeeeLoc = 0;
// 与基准音相差得半音数 音调 跨度(越高声音越尖锐)
let semitones = 0;
// 采样频率 默认：间隔 88200为1秒 44100 44.1kHz
let sampleFrequency = 44.1;
// 基础调，此处以A4为标准，即C调1234567里的 6;
let standHz = 440; // Hz 1秒440次震动 即440个周期
// 一个音所占的字节数
let oneVoiceBytes = 1000 * sampleFrequency * samplingPrecision * tracks;
// 一个音持续的时间 s 速率也可以通过60/musicTime来计算
let musicTime = 1;

var wavHeader = {};
wavHeader.RIFF = wavRead.slice(0,4).toString();
wavHeader.wavLen = wavRead[4] + wavRead[5]*256 + wavRead[6]*256*256 + wavRead[7]*256*256*256;
wavHeader.WAVE = wavRead.slice(8,12).toString();
wavHeader.fmt_ = wavRead.slice(12,16).toString();
wavHeader.size1 = wavRead[16] + wavRead[17]*256 + wavRead[18]*256*256 + wavRead[19]*256*256*256;
wavHeader.formatTag = wavRead[20] + wavRead[21]*256;
wavHeader.channel = wavRead[22] + wavRead[23]*256;
wavHeader.simpleRate = wavRead[24] + wavRead[25]*256 + wavRead[26]*256*256 + wavRead[27]*256*256*256;
wavHeader.bytePerSec = wavRead[28] + wavRead[29]*256 + wavRead[30]*256*256 + wavRead[31]*256*256*256;
wavHeader.blockAlign = wavRead[32] + wavRead[33]*256;
wavHeader.bitPerSample = wavRead[34] + wavRead[35]*256 + wavRead[36]*256*256 + wavRead[37]*256*256*256;
wavHeader.data = wavRead.slice(38, 42).toString();
wavHeader.size2 = wavRead[42] + wavRead[43]*256 + wavRead[44]*256*256 + wavRead[45]*256*256*256;

console.log('wavHeader:', wavHeader);

console.log('wavLength:', wavRead.length);

console.log(wavRead[4],wavRead[5],wavRead[6],wavRead[7])
// 扩充最大长度
wavRead[7] = 1;
wavRead[45] = 1;

// var musicOperas = [-9,-7,-5,-4,-2,0,2,3,5];
// var musicOperas = [-9,-7,-5,-9,-9,-7,-5,-9,-5,-4,-2,-2,-5,-4,-2]; // 两只老虎
var musicOperas = []
var speed = 110;
var srcOperas = [
    {num: 3, level: 0, keep: 1},
    {num: 6, level: -1, keep: .5},
    {num: 6, level: -1, keep: .5},
    {num: 1, level: 0, keep: 1},
    {num: 3, level: 0, keep: 1},
    {num: 2, level: 0, keep: .5},
    {num: 2, level: 0, keep: .25},
    {num: 3, level: 0, keep: .25},
    {num: 2, level: 0, keep: .5},
    {num: 1, level: 0, keep: .5},
    {num: 2, level: 0, keep: .5},
    {num: 1, level: 0, keep: .5},
    {num: 6, level: -1, keep: 1},

    {num: 3, level: 0, keep: 1},
    {num: 6, level: -1, keep: .5},
    {num: 6, level: -1, keep: .5},
    {num: 1, level: 0, keep: 1},
    {num: 3, level: 0, keep: 1},
    {num: 5, level: 0, keep: .5},
    {num: 2, level: 0, keep: .25},
    {num: 3, level: 0, keep: .25},
    {num: 2, level: 0, keep:.5},
    {num: 1, level: 0, keep: .5},
    {num: 2, level: 0, keep: .5},
    {num: 1, level: 0, keep: .5},
    {num: 7, level: -1, keep: .5},
    {num: 5, level: -1, keep: .5},

    
    {num: 3, level: 0, keep: 1},
    {num: 6, level: -1, keep: .5},
    {num: 6, level: -1, keep: .5},
    {num: 1, level: 0, keep: 1},
    {num: 3, level: 0, keep: 1},
    {num: 2, level: 0, keep: .5},
    {num: 2, level: 0, keep: .25},
    {num: 3, level: 0, keep: .25},
    {num: 2, level: 0, keep: .5},
    {num: 1, level: 0, keep: .5},
    {num: 2, level: 0, keep: .5},
    {num: 1, level: 0, keep: .5},
    {num: 6, level: -1, keep: 1},

    {num: 3, level: 0, keep: 1},
    {num: 6, level: -1, keep: .5},
    {num: 6, level: -1, keep: .5},
    {num: 1, level: 0, keep: 1},
    {num: 3, level: 0, keep: 1},
    {num: 5, level: 0, keep: .5},
    {num: 2, level: 0, keep: .25},
    {num: 3, level: 0, keep: .25},
    {num: 2, level: 0, keep:.5},
    {num: 1, level: 0, keep: .5},
    {num: 2, level: 0, keep: .5},
    {num: 1, level: 0, keep: .5},
    {num: 7, level: -1, keep: .5},
    {num: 5, level: -1, keep: .5}

]
// 把简谱转换成无脑谱
function operasTrans(srcOperas) {
    let musicOperas = [];
    let minKeep = Infinity;
    for (let i = 0; i < srcOperas.length; i++) {
        let srcOpera = srcOperas[i];
        if (srcOpera.keep < minKeep) {
            minKeep = srcOpera.keep;
        }
    }
    musicTime = 60 * minKeep / speed;
    for (let i = 0; i < srcOperas.length; i++) {
        let srcOpera = srcOperas[i];
        let _keep = srcOpera.keep;
        while(_keep> 0) {
            musicOperas.push(getMusicOpera(srcOpera.num, srcOpera.level));
            _keep -= minKeep;
        }
    }
    return musicOperas;
}
// 获取对应得半音距离
function getMusicOpera(num, level) {
    return NUM_2_SEMITONES_DIC[num] + level * 12
}

// musicOperas = operasTrans(srcOperas);
musicTime = .2;
musicOperas = [0,1,2,3,4,5,6,7,8,9, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,0,1,2,3,4,5,6,7,8,9, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,0,1,2,3,4,5,6,7,8,9, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
let musicOperas2 = operasTrans(srcOperas);
console.log(musicOperas);
let fileLength = oneVoiceBytes * musicTime * musicOperas.length;
let newWavRead = new Buffer(fileLength);
// 提取wav信息
for (let i = 0; i < 50; i++) {
    newWavRead[i] = wavRead[i];
}
for (var i = 51; i < fileLength;) {
    let idx = i / (oneVoiceBytes * musicTime) | 0;
    for (let t = 0; t < tracks; t++) {
        if (t === 0) {
            semitones = musicOperas[idx];
        } else {
            semitones = musicOperas2[idx];
        }
        let tarHz = standHz * 2**((beeeeeeLoc+semitones)/12)
        // 1Hz可以有多少个字节来表现他
        let canUsedBytes = oneVoiceBytes / tarHz;
        let _h = ((i/tracks)%(canUsedBytes))/(canUsedBytes);
        let h = _h * 512|0;
        // t 0 为左声道，t 1 为右声道
        // t
        // 大致位 整数部分 128.0~255.9 为下面 0.0~127.9为上面
        newWavRead[i++] = h;
        // 精确位 小数部分 128.0~255.9 为下面 0.0~127.9为上面
        newWavRead[i++] = 0;
    }
}
console.log(newWavRead.length)

fs.writeFileSync("test.wav", newWavRead);
